<template>
  <div class="result-table">
    <div ref="tabulator"></div>
  </div>
</template>

<script type="text/javascript">
  import {TabulatorFull} from 'tabulator-tables'
  import _ from 'lodash'
  import dateFormat from 'dateformat'
  import Converter from '../../mixins/data_converter'
  import Mutators, { escapeHtml } from '../../mixins/data_mutators'
import globals from '@/common/globals'
import Papa from 'papaparse'

  export default {
    mixins: [Converter, Mutators],
    data() {
      return {
        tabulator: null,
        actualTableHeight: '100%',
      }
    },
    props: ['result', 'tableHeight', 'query', 'active'],
    watch: {
      active() {
        if (!this.tabulator) return;
        if (this.active) {
          this.tabulator.restoreRedraw()
          this.$nextTick(() => {
            this.tabulator.redraw()
          })
        } else {
          this.tabulator.blockRedraw()
        }
      },
      tableData: {
        handler() {
          this.tabulator.replaceData(this.tableData)
        }
      },
      tableColumns: {
        handler() {
          this.tabulator.setColumns(this.tableColumns)
        }
      },
      tableHeight() {
        this.tabulator.setHeight(this.actualTableHeight)
      }
    },
    computed: {
      tableData() {
          return this.dataToTableData(this.result, this.tableColumns)
      },
      tableTruncated() {
          return this.result.truncated
      },
      cellContextMenu() {
        return [
          {
            label: '<x-menuitem><x-label>Copy Cell</x-label></x-menuitem>',
            action: (_e, cell) => this.$native.clipboard.writeText(cell.getValue())
          },
          {
            label: '<x-menuitem><x-label>Copy Row (JSON)</x-label></x-menuitem>',
            action: (_e, cell) => {
              const data = cell.getRow().getData()
              const fixed = {}
              Object.keys(data).forEach((key) => {
                const v = data[key]
                const column = this.tableColumns.find((c) => c.field === key)
                const nuKey = column ? column.title : key
                fixed[nuKey] = v
              })
              this.$native.clipboard.writeText(JSON.stringify(fixed))
            }
          },
          {
            label: '<x-menuitem><x-label>Copy Row (TSV / Excel)</x-label></x-menuitem>',
            action: (_e, cell) => this.$native.clipboard.writeText(Papa.unparse([cell.getRow().getData()], { header: false, quotes: true, delimiter: "\t", escapeFormulae: true }))
          }
        ]
      },
      tableColumns() {
        const columnWidth = this.result.fields.length > 30 ? globals.bigTableColumnWidth : undefined
        return this.result.fields.map((column) => {
          const result = {
            title: column.name,
            titleFormatter: 'plaintext',
            field: column.id,
            titleDownload: escapeHtml(column.name),
            dataType: column.dataType,
            width: columnWidth,
            mutator: this.resolveTabulatorMutator(column.dataType),
            formatter: this.cellFormatter,
            maxInitialWidth: globals.maxColumnWidth,
            tooltip: true,
            contextMenu: this.cellContextMenu
          }
          return result;
        })
      },
    },
    beforeDestroy() {
      if (this.tabulator) {
        this.tabulator.destroy()
      }
    },
    async mounted() {
      this.tabulator = new TabulatorFull(this.$refs.tabulator, {
        data: this.tableData, //link data to table
        reactiveData: true,
        renderHorizontal: 'virtual',
        columns: this.tableColumns, //define table columns
        height: this.actualTableHeight,
        nestedFieldSeparator: false,
        clipboard: true,
        keybindings: {
          copyToClipboard: false
        },
        downloadConfig: {
          columnHeaders: true
        }
      });
    },
    methods: {
      download(format) {
        const dateString = dateFormat(new Date(), 'yyyy-mm-dd_hMMss')
        const title = this.query.title ? _.snakeCase(this.query.title) : "query_results"
        this.tabulator.download(format, `${title}-${dateString}.${format}`, 'all')
      },
      clipboard() {
        this.tabulator.copyToClipboard("table", true)
        this.$noty.info("Table data copied to clipboard")
      }
    }
	}
</script>
